﻿
using MetroNextTools.NControls;
using MetroNextTools.NData;
using MetroNextTools.NEventArgs;
using MetroNextTools.NHelper;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace MetroNextTools.NPanel
{
    public class ItemLayoutInfo
    {
        public int firstRealizedItemIndex;      //第一个索引
        public int lastRealizedItemIndex;       //最后一个索引
        public double firstRealizedItemTop;     //第一个距离顶部的坐标
        public double firstRealizedOItemLeft;   //第一个距离左侧的坐标
    }

    

    public class NWrapDockVirtualizingPanel : NOrientationVirtualizingPanel
    {
        #region ExtentInfo
        internal class ExtentInfo
        {
            public double _extentHeight;            //期望的高度
            public double _extentWidth;             //期望的宽度
            public double _maxVerticalOffset;       //最大的垂直滚动距离
            public double _maxHorizontalOffset;     //最大的水平滚动距离
        }
        #endregion

        #region Fileds

        private NItemsControl _itemsControl;
        private INRecyclingItemContainerGenerator _generator;
        private bool _isInMeasure;
        Dictionary<UIElement, Rect> _realizedChildLayout = new Dictionary<UIElement, Rect>();

        private Size _viewportSize;
        private Size _extentSize;

        #endregion

        #region Constructor

        public NWrapDockVirtualizingPanel() 
        {
            if (!Windows.ApplicationModel.DesignMode.DesignModeEnabled)
            {
                UIDispatcher.BeginExecute(Initialize);
            }
        }

        #endregion

        #region DepenedencyProperties

        private static void SetVirtualItemIndex(DependencyObject d,int value)
        {
            d.SetValue(VirtualItemIndexProperty, value);
        }

        private static int GetVirtualItemIndex(DependencyObject d)
        {
            return (int)d.GetValue(VirtualItemIndexProperty);
        }

        private static readonly DependencyProperty VirtualItemIndexProperty =
            DependencyProperty.RegisterAttached("VirtualItemIndex", typeof(int), typeof(NWrapDockVirtualizingPanel), new PropertyMetadata(-1));

        #endregion

        #region Properties

        /// <summary>
        /// 后去是否是水平滚动
        /// </summary>
        private bool IsHorziontal
        {
            get { return this.Orientation == Orientation.Horizontal; }
        }

        #endregion

        #region Method
        

        /// <summary>
        /// 初始化方法
        /// </summary>
        private void Initialize()
        {
            _itemsControl = NItemsControl.GetItemsOwner(this);
            _generator = (INRecyclingItemContainerGenerator)ItemContainerGenerator;

            InvalidateMeasure();
        }


        #region Override

        /// <summary>
        /// 滚动方法
        /// </summary>
        protected override void Scrolling()
        {
            base.Scrolling();
            Debug.WriteLine("Scrolling--->");
        }

        protected override void OnItemsChanged(object sender, NItemsChangedEventArgs e)
        {
            base.OnItemsChanged(sender, e);
            InvalidateMeasure();
            
        }

        protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Size availableSize)
        {
            if (this._itemsControl == null)
            {
                return availableSize;
            }
            _isInMeasure = true;                                //正在测算中
            _realizedChildLayout.Clear();                       //在显示的元素信息位置的集合

            ExtentInfo extentInfo = GetExtentInfo(availableSize); //获取边框
            ItemLayoutInfo layoutInfo = CaculateLayouInfo();      //获取内部

            RecycleItems(layoutInfo);

            GeneratorPosition startPos = _generator.GeneratorPositionFromIndex(layoutInfo.firstRealizedItemIndex);
            double currentX = layoutInfo.firstRealizedOItemLeft;
            double currentY = layoutInfo.firstRealizedItemTop;

            bool isHorziontalInsert = Orientation == Orientation.Horizontal;

            _generator.StartAt(startPos, GeneratorDirection.Forward, true);
            int visualIndex = 0; //在Panel中的索引
            for (var itemIndex = layoutInfo.firstRealizedItemIndex; itemIndex <= layoutInfo.lastRealizedItemIndex; itemIndex++, visualIndex++)
            {
                bool newlyRealied;
                UIElement child = _generator.GenertateNext(out newlyRealied) as UIElement;
                SetVirtualItemIndex(child, itemIndex);
                if (newlyRealied)
                {
                    InsertInternalChild(visualIndex, child);
                }
                else
                {
                    if (visualIndex < Children.Count)
                    {
                        if (Children[visualIndex] != child)
                        {
                            var childCurrentIndex = Children.IndexOf(child);
                            if (childCurrentIndex >= 0)
                            {
                                RemoveInternalChildRange(childCurrentIndex, 1);
                            }
                            InsertInternalChild(visualIndex, child);
                        }
                    }
                    else
                    {
                        AddInternalChild(child);
                    }
                }
                _generator.PrepareItemContainer(child);

                //cihld.measure(size);
                //layout the items and record the childRect
            }
            CleanUpItems();
            UpdateScrollInfo(availableSize, extentInfo);
            return availableSize;
        }


        protected override Windows.Foundation.Size ArrangeOverride(Windows.Foundation.Size finalSize)
        {
            foreach (UIElement child in Children)
            {
                child.Arrange(_realizedChildLayout[child]);
            }
            return finalSize;
        }

        #endregion

        /// <summary>
        /// 后去边框内容--这个地方最好结合IScrollInfo来使用
        /// </summary>
        /// <param name="viewportSize"></param>
        /// <returns></returns>
        private ExtentInfo GetExtentInfo(Size viewportSize)
        {
            if (this._itemsControl == null)
            {
                return new ExtentInfo();
            }
            if (IsHorziontal)
            {
                double maxHeight = GetMaxHeight();
                double extentHeight = Math.Max(maxHeight, viewportSize.Height);
                return new ExtentInfo() { _extentHeight = extentHeight, _maxVerticalOffset = extentHeight - viewportSize.Height };
            }
            else
            {
                double maxWidth = GetMaxWidth();
                double extentWidth = Math.Max(maxWidth, viewportSize.Width);
                return new ExtentInfo() { _extentHeight = extentWidth, _maxVerticalOffset = extentWidth - viewportSize.Width };
            }
        }

        /// <summary>
        /// 得到开始测算时的数据
        /// 包括 FirstItemIndex LastItemIndex FirstItemLeft FirstItemTop
        /// </summary>
        /// <returns></returns>
        private ItemLayoutInfo CaculateLayouInfo()
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// 销毁一部分Container
        /// </summary>
        /// <param name="layoutInfo"></param>
        private void RecycleItems(ItemLayoutInfo layoutInfo)
        {
            foreach (var child in Children)
            {
                var vritualItemIndex = GetVirtualItemIndex(child);
                if (vritualItemIndex < layoutInfo.firstRealizedItemIndex || vritualItemIndex > layoutInfo.lastRealizedItemIndex)
                {
                    var generatorPosition = _generator.GeneratorPositionFromIndex(vritualItemIndex);
                    if (generatorPosition.Index > 0)
                    {
                        _generator.Recycle(generatorPosition, 1);
                    }
                }
                SetVirtualItemIndex(child, -1);//做一个标示说明要销毁了
            }
        }

        /// <summary>
        /// 清除不要显示的Item
        /// </summary>
        /// <param name="firstVisibleIndex"></param>
        /// <param name="maxDesiredGenerated"></param>
        private void CleanUpItems()
        {
            for (int i = Children.Count - 1; i >= 0; i--)
            {
                var child = Children[i];
                if (GetVirtualItemIndex(child) == -1)
                {
                    RemoveInternalChildRange(i, 1);
                }
            }
        }

        private void UpdateScrollInfo(Size avialableSize, ExtentInfo extentInfo)
        {
            _viewportSize = avialableSize;
            if (!IsHorziontal)
            {
                _extentSize = new Size(avialableSize.Width, extentInfo._extentHeight);
            }
            else
            {
                _extentSize = new Size(avialableSize.Height, extentInfo._extentWidth);
            }
            InvalidateScrollInfo();
        }

        private void InvalidateScrollInfo()
        {
            if (this.ScrollOwner != null)
            {
                ScrollOwner.InvalidateScrollInfo();
            }
        }
       
        /// <summary>
        /// 获取最大的高度
        /// </summary>
        /// <returns></returns>
        private double GetMaxHeight()
        {
            return 0.0;
        }
        /// <summary>
        /// 获取最大的宽度
        /// </summary>
        /// <returns></returns>
        private double GetMaxWidth()
        {
            return 0.0;
        }

        #endregion

        #region CaculateItems

        private void CaculateItems()
        {
            var items = this._itemsControl.Items;
            foreach (var item in items)
            {

            }
        }

        #endregion
    }
}
